package world;

import java.util.ArrayList;

import org.newdawn.slick.Graphics;

public class Pathing implements Runnable{

	static ArrayList<Event> eventList;
	volatile static boolean run = false;

	@Override
	public  void run() {
		
		run = true;
		move();
	
}


	public synchronized  void move(){
		
		// change to alter movement speed more loops, less choppy
		int loops = 80;
		int sleep = 25;
		
		
		
		if(Player.event != eventList.get(eventList.size() - 1)){
			eventList.get(0).triggerEvent();
			
			
		for(int i = 0; i < eventList.size() - 1; i++){
	
			if(run){
			try {
	
				float deltaX = eventList.get(i).getEvent().getX() - eventList.get(i + 1).getEvent().getX();
				float deltaY = eventList.get(i).getEvent().getY() - eventList.get(i + 1).getEvent().getY();

				
				for(int j = 0; j < loops; j++){
				
			
				if(Math.abs(deltaX) > Math.abs(deltaY)){
					
					if(deltaX < 0){Player.changeAni(3);}else{Player.changeAni(2);}
					
				}
				else{

					if(deltaY > 0){Player.changeAni(0);}else{Player.changeAni(1);}
					
				}
	
				
				
				if(deltaY < 0){	
				Player.setX(Player.x - (deltaX/loops));
			    Player.setY(Player.y - (deltaY/loops));
				}else{
					Player.setX(Player.x - (deltaX/loops));
				    Player.setY(Player.y - (deltaY/loops));
				}
			    
			   World.centerView();
				Thread.sleep(sleep);
				} eventList.get(i + 1).triggerEvent();
				
				
				
			
			}catch (InterruptedException e) {e.printStackTrace();}
		}

		
		}
		
		if(run){
		Player.changeAni(1);
		Player.setEvent(eventList.get((eventList.size() - 1)));
		World.centerView();
		}
		
	}
		
		try {
			this.finalize();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		run = false;
	}

	public static void setEvent(ArrayList<Event> eventList){
		
		Pathing.eventList = eventList;
		
	}
	
	public static void startUp(){
		
		run = true;
		
	}
	
	
	public static void shutdown(){
		
		run = false;
		
	}
	
	
	public static void buildRoute(Event toEvent){

		Pathing.setEvent(findRoute(toEvent));

		if(Pathing.eventList != null && Pathing.eventList.size() > 1){
		new Thread(new Pathing()).start();
		}
	}

	public static ArrayList<Event> findRoute(Event toEvent){

		ArrayList<Event> route = new ArrayList<Event>();
		ArrayList<Event> ordered = new ArrayList<Event>();

		
		if(findRoute(null, Player.event, toEvent, route)){
			
			for(int l = 0; l < route.size(); l++){System.out.println(route.get(l).getName() + " in route");}
			
			int routeSize = route.size();
			route.remove(Player.event);
			ordered.add(Player.event);
			
			Event current = Player.event;

			do{
			
			for(int i = 0; i < route.size(); i ++){
				
				Event check = route.get(i);
				
				if(isPathed(current, check)){

					//move to next event
					current = check;  
					//add event in ordered to new list
					ordered.add(check); 
					//remove event to prevent redundancy
					route.remove(check);
				}
			}
			
			}while(ordered.size() != routeSize);

			System.out.println(route.size() + " route size");
			
		return ordered;
		}else{return null;}
	}



	public static boolean findRoute(Event past, Event current, Event toEvent, ArrayList<Event> route){

		if(!checkIn(route, toEvent)){
		
		for(int i = 0; i < current.getPathCount(); i++){
			
			Path path = current.getPaths().get(i);
			
			if(path.isActive()){
			Event opp = path.getOpposite(current);
		
			if(current == toEvent){if(!checkIn(route, current)){route.add(current);}return true;}else
				if(path.getOpposite(current) != past && !checkIn(route, opp)
						&& findRoute(current, opp, toEvent, route)){if(!checkIn(route, current)){route.add(current);}return true;}

			}
		}

		return false;
	}else{return true;}
	}



	public static boolean checkIn(ArrayList list, Event event){

		for(int i = 0; i < list.size(); i++){
			
			if(event == list.get(i)){return true;}
			
		}
		
		return false;

	}

	
	public static boolean isPathed(Event event1, Event event2){
		
		if(event1 == null || event2 == null){return false;}
		
		
		for(int i = 0; i < event1.getPathCount(); i++){
		
			if(event1.getPaths().get(i).isActive() && event1.getPaths().get(i).getOpposite(event1) == event2){return true;}

		}
		
		return false;
		
	}	
	
}
